#include "multidisplay.h"
#include "drawimage.h"
#include "showclock.h"
#include <QVBoxLayout>
#include <QGridLayout>
#include <QLayout>
#include <QPushButton>
#include <QGroupBox>
#include <QSplitter>
#include <QFileDialog>
#include <QtAlgorithms>
#include <QMessageBox>

MultiDisplay::MultiDisplay(QWidget *parent)
    : QMainWindow(parent)
{
    initialize();
}

MultiDisplay::~MultiDisplay()
{
    on_closeAll();
    delete displayList;
}

void MultiDisplay::initialize()
{
    //TODO
    myTimer = NULL;
//    if (myTimer == NULL) myTimer = new QTimer();
//    connect(myTimer, SIGNAL(timeout()), this, SLOT(update()));
//    myTimer->start(50);

    numScreens = desktop.numScreens();
    this->setMinimumHeight(450);
    this->setMinimumWidth(1100);

    createAction();
    createInterface();

    displayList = new QList <DisplayWidget *>;
}

void MultiDisplay::createAction()
{
    //TODO
//    actDrawImage = new QAction(tr("Show Image"), this);
//    connect(actDrawImage, SIGNAL(triggered()), SLOT(ac_DrawImage()));
//    this->addAction(actDrawImage);

//    this->setContextMenuPolicy(Qt::ActionsContextMenu);
}

void MultiDisplay::createInterface()
{
    //TODO
    QWidget* mainContent = new QWidget;
    QHBoxLayout* mainHLayout = new QHBoxLayout();
    mainContent->setLayout(mainHLayout);

//    QSplitter *splitter = new QSplitter(Qt::Vertical,this);
    mainHLayout->addLayout(createPreviews());
    mainHLayout->addLayout(createTaskPanel());

    this->setCentralWidget(mainContent);
}

QGridLayout *MultiDisplay::createPreviews()
{
    //TODO
    QGridLayout* displayGLayout = new QGridLayout();
    previewList = new QList <PreviewScr *>;
    for (int i=1; i<numScreens; i++)
    {
        PreviewScr *dis = new PreviewScr(NULL, desktop.screen(i), i);
        dis->setFocusPolicy(Qt::StrongFocus);
        dis->setFixedHeight(PREVIEWHEIGHT);
        dis->setFixedWidth(PREVIEWWIDTH);
        connect(dis, SIGNAL(drawImage(int)), SLOT(ac_DrawImage(int)));
        connect(dis, SIGNAL(showClock(int)), SLOT(ac_ShowClock(int)));
        previewList->append(dis);
//        displayGLayout->addWidget(dis, i/4*2, i%4*2);
        displayGLayout->addWidget(dis, (i-1)/4*2, (i-1)%4*2);

//        QMessageBox::information(desktop.screen(i), tr("Info"), tr("Screen No.%1").arg(i));
    }

    for (int i=numScreens; i<9; i++)
    {
        QLabel *display = new QLabel();
        display->setText(tr("Projector %1 not found.").arg(i));
        displayGLayout->addWidget(display, (i-1)/4*2, (i-1)%4*2);
    }
    return displayGLayout;
}

QVBoxLayout *MultiDisplay::createTaskPanel()
{
    //TODO
    QVBoxLayout *taskVLayout = new QVBoxLayout();

    //Screens Message start
    QLabel *scrMsg = new QLabel(
                tr("There is(are) %1 projectors\nin the system")
                .arg(numScreens));
    scrMsg->setFixedWidth(TASKWIDGETWIDTH);
    taskVLayout->addWidget(scrMsg);
    //Screens Message end

    //Projectors check boxes start
    QGroupBox *projectorsGroup = new QGroupBox(tr("Projector(s)"));
    QGridLayout *projectorsGLayout = new QGridLayout();
    projectorList = new QList <QCheckBox *>;
    for (int i=1; i<numScreens; i++)
    {
        QCheckBox *projector = new QCheckBox(tr("%1").arg(i));
        projector->setChecked(true);
        projectorList->append(projector);
        projectorsGLayout->addWidget(projector, (i-1)/4*2, (i-1)%4*2);
    }
    projectorsGroup->setLayout(projectorsGLayout);
    taskVLayout->addWidget(projectorsGroup);
    //Projectors check boxes end

    //Display message label start
    displayMsg = new QLabel(tr("Showing Desktop"));
    displayMsg->setFixedWidth(TASKWIDGETWIDTH);
    taskVLayout->addWidget(displayMsg);
    //Display message label end

    //Image group start
    imageLabel = new QLabel(tr("No image"));
    QPushButton *btn_image = new QPushButton(tr("Image"));
    btn_image->setFixedWidth(TASKWIDGETWIDTH-20);
    QVBoxLayout *imageLayout = new QVBoxLayout();
    imageLayout->addWidget(imageLabel);
    imageLayout->addWidget(btn_image);
    QGroupBox *imageGroup = new QGroupBox(tr("Image"));
    imageGroup->setLayout(imageLayout);
    connect(btn_image, SIGNAL(clicked()), SLOT(on_image()));
    taskVLayout->addWidget(imageGroup);
    //Image group end

    //Clock button start
    QPushButton *btn_clock = new QPushButton(tr("Clock"));
    btn_clock->setFixedWidth(TASKWIDGETWIDTH);
    taskVLayout->addWidget(btn_clock);
    connect(btn_clock, SIGNAL(clicked()), SLOT(on_clock()));
    //Clock button end

    //Color button start
    QPushButton *btn_color = new QPushButton(tr("Color"));
    btn_color->setFixedWidth(TASKWIDGETWIDTH);
    btn_color->setEnabled(false);
    taskVLayout->addWidget(btn_color);
    //Color button end

    //Structureded light button start
    QPushButton *btn_slight = new QPushButton(tr("Structured Light"));
    btn_slight->setFixedWidth(TASKWIDGETWIDTH);
    btn_slight->setEnabled(false);
    taskVLayout->addWidget(btn_slight);
    //Structureded light button end

    //Refresh button start
    QPushButton *btn_refresh = new QPushButton(tr("Refresh"));
    btn_refresh->setFixedWidth(TASKWIDGETWIDTH);
    taskVLayout->addWidget(btn_refresh);
    connect(btn_refresh, SIGNAL(clicked()), SLOT(on_refresh()));
    //Refresh button end

    //Close all button start
    QPushButton *btn_closeAll = new QPushButton(tr("Close all"));
    btn_closeAll->setFixedWidth(TASKWIDGETWIDTH);
    taskVLayout->addWidget(btn_closeAll);
    connect(btn_closeAll, SIGNAL(clicked()), SLOT(on_closeAll()));
    //Close all button end

    //Exit button start
    QPushButton *btn_exit = new QPushButton(tr("Exit"));
    btn_exit->setFixedWidth(TASKWIDGETWIDTH);
    taskVLayout->addWidget(btn_exit);
    connect(btn_exit, SIGNAL(clicked()), SLOT(on_exit()));
    //Exit button end

    return taskVLayout;
}

void MultiDisplay::on_refresh()
{
    this->update();
}

void MultiDisplay::on_image()
{
    //TODO
    //Check selected
    int checked = 0;
    if (!projectorList->isEmpty()) {
        for (int i=0; i<projectorList->count(); i++)
        {
            if (projectorList->at(i)->isChecked()) {
                checked++;
            }
        }
    }

    if (checked > 0){
        QString imgPath = QFileDialog::getOpenFileName(this,
                                     "Selected an image file",
                                     ".",
                                     "*.jpg, *.bmp *.png");
        if (imgPath.length() > 0)
        {
            for (int i=0; i<projectorList->count(); i++)
            {
                if (projectorList->at(i)->isChecked()) {
                    //Show image on selected display;
                    int proNum = projectorList->at(i)->text().toInt();
                    showImageonDisplay(proNum, imgPath);
                }
            }
        }
    }
    this->update();
}

void MultiDisplay::checkDisplay(int scrNum)
{
    if (displayList->isEmpty())
        return;
    else {
        DisplayWidget *dis;
        for (int i=0; i<displayList->count(); i++)
        {
            if (displayList->at(i)->screenNumber() == scrNum)
            {
                dis = displayList->at(i);
                displayList->removeOne(dis);
                delete dis;
            }
        }
    }
}

void MultiDisplay::on_closeAll()
{
    if (!displayList->isEmpty())
    {
        qDeleteAll(displayList->begin(), displayList->end());
        displayList->clear();
    }
    myTimer->stop();
    this->update();
}

void MultiDisplay::on_exit()
{
    on_closeAll();
    this->close();
}

void MultiDisplay::ac_DrawImage(int num)
{
    //TODO
#ifdef DEBUG
    qDebug() << "======Send screen No." << num;
#endif
    if (!previewList->isEmpty())
    {
        QString imgPath = QFileDialog::getOpenFileName(this,
                                     "Selected an image file",
                                     ".",
                                     "*.jpg, *.bmp *.png");
        if (imgPath.length() > 0)
            {
            int i;
            PreviewScr *dis;
            for (i=0; i<previewList->count(); i++)
            {
                if (previewList->at(i)->linkedScreenNumber() == num)
                {
                    dis = previewList->at(i);
                    break;
                }
            }
            showImageonDisplay(num, imgPath);
        }
    }
}

void MultiDisplay::showImageonDisplay(int proNum, QString imgPath)
{
#ifdef DEBUG
    qDebug() << "======Show image on screen" << proNum;
#endif
    checkDisplay(proNum);
    QWidget *screen = desktop.screen(proNum);
    DrawImage *w = new DrawImage(screen, imgPath, proNum);
    w->showFullScreen();
    displayList->append(w);
#ifdef DEBUG
    qDebug() << "======screen:" << w->screenNumber();
#endif
    this->update();
}

void MultiDisplay::on_clock()
{
    int checked = 0;
    if (!projectorList->isEmpty()) {
        for (int i=0; i<projectorList->length(); i++)
        {
            if (projectorList->at(i)->isChecked()) {
                checked++;
            }
        }
    }

    if (checked > 0){
        if (myTimer == NULL) myTimer = new QTimer();
        for (int i=0; i<projectorList->length(); i++)
        {
            if (projectorList->at(i)->isChecked()) {
                int proNum = projectorList->at(i)->text().toInt();
                showClockonDisplay(proNum);
            }
        }
        myTimer->start(20);
        connect(myTimer, SIGNAL(timeout()), SLOT(update()));
    }
}

void MultiDisplay::ac_ShowClock(int num)
{
    if (!previewList->isEmpty())
    {
        int i;
        PreviewScr *dis;
        for (i=0; i<previewList->count(); i++)
        {
            if (previewList->at(i)->linkedScreenNumber() == num)
            {
                dis = previewList->at(i);
                break;
            }
        }
        if (myTimer == NULL) myTimer = new QTimer();
        showClockonDisplay(num);
        myTimer->start(20);
    }
}

void MultiDisplay::showClockonDisplay(int proNum)
{
    //TODO
    checkDisplay(proNum);
    QWidget *screen = desktop.screen(proNum);
    ShowClock *w = new ShowClock(screen, proNum);
    w->showFullScreen();
    connect(myTimer, SIGNAL(timeout()), w, SLOT(drawClock()));
//    connect(w, SIGNAL(contentRepaint()), this, SLOT(update()));
    displayList->append(w);
    this->update();
}
